#!/usr/bin/python 
# -*- coding=utf-8 -*-
'''
block handler
handling client block request
'''
import tornado.ioloop
import tornado.web
import json
import logging
import zc.zk

class BlockHandler(tornado.web.RequestHandler):
    def initialize(self, zk, lb):
        self.zk = zk
        self.lb = lb

    def get(self, topic, tid):
        # validate user

        # convert <topic, tid> to <dsg, topic, tid>
        topic_path = '/iotmq/topic/' + topic
        logging.debug('get topic: %s' % topic_path)
        # get blok
        blocks = self.zk.children(topic_path)
        for block in sorted(blocks, key=int):
            block_path = topic_path + '/' + block
            block_info = dict(self.zk.properties(block_path))
            logging.debug('read block(%s) %s' % (block_path, block_info))
            if int(block_info['end_id']) > int(tid):
                self.write(json.dumps(block_info))
                return
        # not find
        result = {
            'status': 'error',
            'message:': 'block not find'
        }
        self.write(json.dumps(result))

    def post(self, topic, tid):
        # get block list
        topic_path = '/iotmq/topic/' + topic
        blocks = []
        try:
            blocks = sorted(self.zk.children(topic_path), key=int)
        except Exception, e:
            logging.exceptiion('get block(%s) failed, %s' % (topic_path, str(e)))
            self.write('{"status":"error", "message":"get block failed"}')
            return

        # need create new block?
        if not len(blocks):
            block_info = {
                'id': 1,
                'start_id': 0,
                'end_id': 0xFFFFFFFFFFFFFFFF,
                'ds_group': self.lb.findNewDS(),
            }
            self.zk.create(topic_path + '/1', json.dumps(block_info), zc.zk.OPEN_ACL_UNSAFE)
            logging.info('create new block, %s' % (topic_path + '/1'))
            self.write(json.dumps(block_info))
        else:
            # check tid
            if tid:
                # close last block and create new
                block = blocks[-1]
                block_path = topic_path + '/' + block
                block_info = self.zk.properties(block_path)
                block_info.update(end_id = int(tid))
                
                # create new block
                new_block = int(block) + 1
                block_path = '%s/%d' % (topic_path, new_block)
                new_block_info = {
                    'id': new_block,
                    'start_id': int(tid) + 1,
                    'end_id': 0xFFFFFFFFFFFFFFFF,
                    'ds_group': self.lb.findNewDS()
                }
                try:
                    self.zk.create(block_path, json.dumps(new_block_info), zc.zk.OPEN_ACL_UNSAFE)
                    logging.info('close block, and create new block(%s)' % block_path)
                    self.write(json.dumps(new_block_info))
                except Exception, e:
                    logging.exception('create new block(%s) failed' % new_block)
                return
            else:
                # find last block and reaturn
                block = blocks[-1]
                block_path = topic_path + '/' + block
                block_info = dict(self.zk.properties(block_path))
                logging.debug('find block(%s), property: %s' % (block_path, block_info))
                self.write(json.dumps(block_info))
                return
